using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using SCore.Util;

namespace SCore.Util
{
    public class FileLoader
    {
        public interface IFileLoader
        {
            byte[] ReadAllBytes(string path);
            string ReadAllText(string path);

            string GetURL(string path);
        }

        public class StreamingAssetsLoader : IFileLoader
        {
            private string _prefix;

            public StreamingAssetsLoader(string prefix = null)
            {
                _prefix = prefix;
            }

            public byte[] ReadAllBytes(string path)
            {
                if (_prefix != null)
                {
                    path = String.Format("{0}/{1}", _prefix, path);
                }

                return UnityUtils.ReadStreamingAssets(path);
            }

            public string ReadAllText(string path)
            {
                if (_prefix != null)
                {
                    path = String.Format("{0}/{1}", _prefix, path);
                }

                return UnityUtils.ReadStreamingAssetsText(path);
            }

            public string GetURL(string path)
            {
                if (_prefix != null)
                {
                    return string.Format("{0}/{1}", _prefix, path);
                }

                return path;
            }
        }

        public class SingleDirectoryLoader : IFileLoader
        {
            private string _directory;

            public SingleDirectoryLoader(string directory)
            {
                _directory = directory;
            }

            private StringBuilder _sb = new StringBuilder(1024);

            private string GetFullPath(string path)
            {
                _sb.Clear();
                _sb.Append(_directory);
                _sb.Append('/');
                _sb.Append(path);
                return _sb.ToString();
            }

            public byte[] ReadAllBytes(string path)
            {
                var fullPath = GetFullPath(path);
                if (!File.Exists(fullPath))
                    return null;
                return File.ReadAllBytes(fullPath);
            }

            public string ReadAllText(string path)
            {
                var fullPath = GetFullPath(path);
                if (!File.Exists(fullPath))
                    return null;
                return File.ReadAllText(fullPath);
            }

            public string GetURL(string path)
            {
                return GetFullPath(path);
            }
        }

        public class MultiDirectoryFileLoader : IFileLoader
        {
            private string[] _directory;

            public MultiDirectoryFileLoader(string[] directory)
            {
                _directory = directory;
            }

            private StringBuilder _sb = new StringBuilder(1024);

            private string GetFullPath(string directory, string path)
            {
                _sb.Clear();
                _sb.Append(directory);
                _sb.Append('/');
                _sb.Append(path);
                return _sb.ToString();
            }

            public byte[] ReadAllBytes(string path)
            {
                foreach (var directory in _directory)
                {
                    var fullPath = GetFullPath(directory, path);
                    if (File.Exists(fullPath))
                        return File.ReadAllBytes(fullPath);
                }

                return null;
            }

            public string ReadAllText(string path)
            {
                foreach (var directory in _directory)
                {
                    var fullPath = GetFullPath(directory, path);
                    if (File.Exists(fullPath))
                        return File.ReadAllText(fullPath);
                }

                return null;
            }

            public string GetURL(string path)
            {
                foreach (var directory in _directory)
                {
                    var fullPath = GetFullPath(directory, path);
                    if (File.Exists(fullPath))
                        return fullPath;
                }

                return null;
            }
        }

        public class CombineFileLoader : IFileLoader
        {
            private List<IFileLoader> _loders = new List<IFileLoader>();

            public CombineFileLoader()
            {
            }

            public void AddFileLoader(IFileLoader loader)
            {
                _loders.Add(loader);
            }

            public byte[] ReadAllBytes(string path)
            {
                foreach (var fileLoader in _loders)
                {
                    byte[] ret = fileLoader.ReadAllBytes(path);
                    if (ret != null)
                        return ret;
                }

                return null;
            }

            public string ReadAllText(string path)
            {
                foreach (var fileLoader in _loders)
                {
                    string ret = fileLoader.ReadAllText(path);
                    if (ret != null)
                        return ret;
                }

                return null;
            }

            public string GetURL(string path)
            {
                foreach (var fileLoader in _loders)
                {
                    string p = fileLoader.GetURL(path);
                    if (p != null)
                    {
                        return p;
                    }
                }

                return null;
            }
        }
    }
}